package com.demo;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * cyclic  环的；循环的；周期的
 * barrier n. 障碍物，屏障；界线
 * CyclicBarrier 可循环的障碍物，   类支持线程集内周期性Barrier同步。
 * 公司组织周末聚餐吃饭、首先各自从家里到聚餐地点，全部到齐之后，才开始一起吃饭(同步点)，
 * 假如人员没有到齐，到的人只能等到在哪里(阻塞)，直到所有人都到齐之后才开始吃饭
 * 吃完饭之后、到步步高广场集合，开始xxx活动
 */
public class CyclicBarrierDemo {

	public static void main(String[] args) {
		// 3个人聚餐
		CyclicBarrier cyclicBarrier=new CyclicBarrier(3 , new  Runnable(){

			@Override
			public void run() {
				try {
					System.out.println("人员全部到齐了，各自拍照留念.....");
					Thread.sleep( (long) (Math.random()*10000) );
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}});
		//线程池
		ExecutorService threadPool=Executors.newCachedThreadPool();
		//模拟3个用户、3个线程
		for(int i=0; i<3; i++){
			int user = i+1;
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					try {
						//模拟每个人来的时间不一样
						Thread.sleep( (long) (Math.random()*10000) );
						System.out.println(user +"号用户到达聚餐点，当前已有"+( cyclicBarrier.getNumberWaiting()+1));
						int count = cyclicBarrier.await();//等待
						if (user == 1) {
							System.out.println("拍照结束...人员全部到齐，开始吃饭.....");							
						}
						Thread.sleep( (long) (Math.random()*10000) );
						System.out.println(user+"号用户吃完饭....准备回家.....");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};
			threadPool.execute(runnable);
		}
		threadPool.shutdown();
	}

}
